import datetime
import json
import os
import threading
import time

import cv2
import requests

from logger import log
from objectdetection import draw_polygon_points
from settings import settings


class Snapshot:
    # 捕获RTSP流中的图像
    def capture_image_from_rtsp(self, stream_url, polygon_points_str=''):
        try:
            os.environ["OPENCV_FFMPEG_CAPTURE_OPTIONS"] = "timeout;5000"
            cap = cv2.VideoCapture(stream_url, cv2.CAP_FFMPEG)
            # cap = cv2.VideoCapture(stream_url)
            cap.set(cv2.CAP_PROP_OPEN_TIMEOUT_MSEC, 5 * 1000)
            cap.set(cv2.CAP_PROP_READ_TIMEOUT_MSEC, 5 * 1000)
            if not cap.isOpened():
                log.info("capture_image_from_rtsp not cap.isOpened()")
                return None
            for i in range(10):
                cap.read()
            ret, frame = cap.read()
            jpg_as_text = None
            if ret:
                frame = cv2.resize(frame, (640, 360))
                if polygon_points_str != '' and polygon_points_str != '[]':
                    polygon_points = json.loads(polygon_points_str)
                    draw_polygon_points(frame, polygon_points)
                # 将图像编码为JPEG格式
                _, buffer = cv2.imencode('.jpg', frame)
                # 转换为字节
                jpg_as_text = buffer.tobytes()
            else:
                log.info("Error: unable to capture image")
            cap.release()
            return jpg_as_text
        except Exception as e:
            log.exception(e)

    def check_camera_from_rtsp(self, stream_url):
        try:
            cap = cv2.VideoCapture(stream_url)
            if not cap.isOpened():
                log.info("check_camera_from_rtsp not cap.isOpened()")
                return None
            for i in range(10):
                cap.read()
            ret, frame = cap.read()
            cap.release()
            return ret
        except Exception as e:
            log.exception(e)

    # 上传图像
    def upload_image(self, image_bytes):
        try:
            # 创建表单数据
            files = {'contractFile': ('img.jpg', image_bytes)}
            # 设置请求的URL
            url = 'https://' + settings.host + '/api/account/oss/fileUpload?accessCode=oss'
            # 发送POST请求
            response = requests.post(url, files=files, verify=False, timeout=10)
            response.raise_for_status()  # 如果请求返回了错误状态码，这会抛出异常
            # 处理响应
            log.info(f"图片上传数据返回:{response.json()}")
            snapshotUrl = response.json()['data']
            return snapshotUrl

        except Exception as error:
            # 打印错误信息
            log.info("uploadOss2 error:", error)

    def upload_snapshot(self, stream_id, snapshotUrl):
        try:
            params = {
                "id": stream_id,
                "snapshotUrl": snapshotUrl,
                "platformId": settings.platformId,
                "platformName": settings.platformName
            }
            requests_post = requests.post('https://' + settings.host + '/api/weigh/internal/vs_stream/snapshot',
                                          json=params)
            requests_post.raise_for_status()  # 如果请求返回了错误状态码，这会抛出异常
            log.info(f"上传完成数据返回:{requests_post.json()}")
        except Exception as error:
            log.exception("uploadSnapshot error:", error)

    def capture_logic(self):
        while True:
            try:
                # todo 定时监测摄像头是否离线
                # 获取当前时间
                current_time = datetime.datetime.now()
                # 如果当前分钟是00，并且秒数在0-59之间，则执行任务
                if current_time.minute == 0:
                    # 等待60秒，确保任务不会在同一分钟内执行多次
                    log.info("Capturing image...")
                    for item in settings.streams:
                        # 如果找到匹配的id，获取对应的rtsp
                        stream_id = item['id']
                        stream_url = item['rtsp']
                        if item['cameraRtsp'] is not None and item['cameraRtsp'] != '':
                            stream_url = item['cameraRtsp']
                        polygon_points_str = item['polygonPoints']
                        log.info(f"抓拍上传：{stream_id}|{item['name']}|{polygon_points_str}|{stream_url}")
                        image_bytes = self.capture_image_from_rtsp(stream_url, polygon_points_str)
                        if image_bytes is not None:
                            # log.info("Uploading image...")
                            url = self.upload_image(image_bytes)
                            if url is not None:
                                self.upload_snapshot(stream_id, url)
                        else:
                            log.info("Failed to capture image")
                    log.info("Capturing image end")
                    time.sleep(60)
                # if current_time.minute % 5 == 0:
                #     log.info("Test camera...")
                #     for item in settings.streams:
                #         stream_url = item['rtsp']
                #         ret = self.check_camera_from_rtsp(stream_url)
                #         if not ret:
                #             # todo 上传异常事件
                #             date = current_time
                #             full_year = metric.get_date_str(date)
                #             metric.send("vsNode", {"deviceName": settings.code, "cameraName": item['name'],
                #                                    "platformName": settings.platformName},
                #                         "cameraDeadline", int(full_year))
                # 短暂睡眠减少循环频率
                time.sleep(1)
            except Exception as e:
                log.exception(e)

    def test_post(self):
        stream_url = "rtsp://admin:admin@192.168.110.100:8557/h264"
        image_bytes = self.capture_image_from_rtsp(stream_url)
        if image_bytes is not None:
            log.info("Uploading image...")
            url = self.upload_image(123)
            self.upload_snapshot(123, url)
        else:
            log.info("Failed to capture image")

    # 定时任务
    def init(self):
        thread = threading.Thread(target=self.capture_logic)
        thread.start()


snapshot = Snapshot()

if __name__ == '__main__':
    settings.host = 'platform.wechain360.com'
    settings.platformName = '测试站台'
    settings.platformId = 5
    snapshot.test_post()
